<?php

namespace App\Http\Controllers;

use App\Events\Out\EventLuckyBagGotLesson;
use App\Events\Out\EventLuckyBagGotMoney;
use App\Exceptions\LuckyBagNotFoundException;
use App\Exceptions\LuckyBagExpiredException;
use App\Exceptions\StudentLuckyBagUpperLimitException;
use App\Exceptions\LuckyBagGrabbedOverException;
use App\Models\LuckyBag;
use App\Models\LuckyBagLog;
use App\Models\StudentFirstBillingTime;
use App\Facades\KafkaBridge;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Laravel\Lumen\Routing\Controller as BaseController;

class LuckyBagController extends BaseController
{
    //

    public function retrieve(Request $request)
    {
        $this->validate($request, [
            'code' => 'required|string'
        ]);

        $studentId = intval($request->header("X-Authenticated-Userid"));
        $shareCode = base64_decode($request->input('code'));
        $bag = LuckyBag::where('appointment_id', $shareCode)->first();
        if (empty($bag)) {
            throw new  LuckyBagNotFoundException();
        }

        $me = null;
        $status = LuckyBag::STATUS_OK;
        $studentBag = LuckyBagLog::where('bag_id', $bag->getId())->where('student_id', $studentId)->first();
        if (!empty($studentBag)) {
            $status = LuckyBag::STATUS_GRABBED;
            $me = [
                'type' => $studentBag->getType(),
                'amount' => $studentBag->getAmount()
            ];
        } else if ($bag->getGrabNum() >= LuckyBag::TOTAL_BAG_NUM) {
            $status = LuckyBag::STATUS_DONE;
        }

        if ($bag->checkLuckyBagIsExpired()) {
            $status = LuckyBag::STATUS_EXPIRED;
        }

        $grabs = null;
        if ($bag->logs()->count() > 0) {
            foreach ($bag->logs()->get() as $log) {
                $temp = [];
                $temp['studentId'] = $log->getStudentId();
                $temp['createdAt'] = $log->getCreatedAt()->getTimestamp();
                $temp['type'] = $log->getType();
                $temp['amount'] = $log->getAmount();
                $grabs[] = $temp;
            }
        }

        $doneSeconds = 0;
        if ($status == LuckyBag::STATUS_DONE) {
            $doneSeconds = $grabs[count($grabs) - 1]['createdAt'] - $grabs[0]['createdAt'];
        }

        return new JsonResponse([
            'studentId' => $bag->getStudentId(),
            'status' => $status,
            'grabs' => $grabs,
            'me' => $me,
            'doneSeconds' => $doneSeconds,
        ]);
    }

    public function retrieveForPublic(Request $request)
    {
        $this->validate($request, [
            'code' => 'required|string'
        ]);
        $shareCode = base64_decode($request->input('code'));
        $bag = LuckyBag::where('appointment_id', $shareCode)->first();
        if (empty($bag)) {
            throw new  LuckyBagNotFoundException();
        }

        $status = LuckyBag::STATUS_OK;
        if ($bag->getGrabNum() >= LuckyBag::TOTAL_BAG_NUM) {
            $status = LuckyBag::STATUS_DONE;
        }

        $grabs = null;
        if ($bag->logs()->count() > 0) {
            foreach ($bag->logs()->get() as $log) {
                $temp = [];
                $temp['studentId'] = $log->getStudentId();
                $temp['createdAt'] = $log->getCreatedAt()->getTimestamp();
                $temp['type'] = $log->getType();
                $temp['amount'] = $log->getAmount();
                $grabs[] = $temp;
            }
        }

        if ($bag->checkLuckyBagIsExpired()) {
            $status = LuckyBag::STATUS_EXPIRED;
        }

        $doneSeconds = 0;
        if ($status == LuckyBag::STATUS_DONE) {
            $doneSeconds = $grabs[count($grabs) - 1]['createdAt'] - $grabs[0]['createdAt'];
        }

        return new JsonResponse([
            'studentId' => $bag->getStudentId(),
            'status' => $status,
            'grabs' => $grabs,
            'doneSeconds' => $doneSeconds,
        ]);
    }

    public function grabLuckyBag(Request $request)
    {
        $this->validate($request, [
            'code' => 'required|string'
        ]);

        $studentId = intval($request->header("X-Authenticated-Userid"));
        $shareCode = base64_decode($request->input('code'));
        $bag = LuckyBag::where('appointment_id', $shareCode)->first();
        if (empty($bag)) {
            throw new  LuckyBagNotFoundException();
        }

        if ($bag->checkLuckyBagIsExpired()) {
            throw new  LuckyBagExpiredException();
        }

        if ($bag->getGrabNum() >= LuckyBag::TOTAL_BAG_NUM || $bag->getStatus() == LuckyBag::STATUS_DONE) {
            throw new  LuckyBagGrabbedOverException();
        }

        $studentBag = LuckyBagLog::where('bag_id', $bag->getId())->where('student_id', $studentId)->first();
        if (!empty($studentBag)) {
            return new JsonResponse([
                'type' => $studentBag['type'],
                'amount' => $studentBag['amount'],
            ]);
        }

        $studentTodayBagNum = LuckyBagLog::where('student_id', $studentId)->where('created_at', '>=', Carbon::today())->count();
        if ($studentTodayBagNum >= LuckyBagLog::UPPER_LIMIT) {
            throw new  StudentLuckyBagUpperLimitException();
        }

        $bag->increaseGrabNum();

        //福袋被抢了8次，福袋发起人额外获得2元奖学金
        if ($bag->getGrabNum() >= 8 && $bag->getStatus() == LuckyBag::STATUS_OK) {
            $bag->setStatus(LuckyBag::STATUS_DONE);
            $bag->save();
            $amount = 2;
            //发event到cash.billing.api，发放现金
            $event = new EventLuckyBagGotMoney();
            $event->studentId = $bag->getStudentId();
            $event->appointmentId = $bag->getAppointmentId();
            $event->amount = $amount;
            $event->type = 0;
            KafkaBridge::push($event);
        } else {
            $bag->save();
        }

        $studentFirstBag = LuckyBagLog::where('student_id', $studentId)->first();
        $firstBilling = StudentFirstBillingTime::find($studentId);
        if (empty($firstBilling) && empty($studentFirstBag)) {//获取课时
            $type = LuckyBagLog::TYPE_LESSON;
            $amount = 0;
            $luckyBagLog = new LuckyBagLog();
            $luckyBagLog->setBagId($bag->getId());
            $luckyBagLog->setStudentId($studentId);
            $luckyBagLog->setType($type);
            $luckyBagLog->save();
            //发event到billing.api，发放课时
            $event = new EventLuckyBagGotLesson();
            $event->studentId = $studentId;
            KafkaBridge::push($event);
        } else {//获取奖学金
            $type = LuckyBagLog::TYPE_MONEY;
            $amount = rand(1, 20)/10;
            $luckyBagLog = new LuckyBagLog();
            $luckyBagLog->setBagId($bag->getId());
            $luckyBagLog->setStudentId($studentId);
            $luckyBagLog->setType($type);
            $luckyBagLog->setAmount($amount);
            $luckyBagLog->save();
            //发event到cash.billing.api，发放现金
            $event = new EventLuckyBagGotMoney();
            $event->studentId = $studentId;
            $event->appointmentId = $bag->getAppointmentId();
            $event->amount = $amount;
            $event->type = 1;
            KafkaBridge::push($event);
        }

        return new JsonResponse([
            'type' => $type,
            'amount' => $amount
        ]);
    }
}
